package monitor

import (
	"context"
	"github.com/prometheus/client_golang/api"
	"fmt"
	"github.com/prometheus/client_golang/api/prometheus/v1"
	"time"
	"github.com/prometheus/common/model"
	"math"
	"strconv"
)

type Mysql string   //ipaddr

func (db Mysql)Uptime() (uptime string, err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
		return
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()

	q := fmt.Sprintf("mysql_global_status_uptime{instance=~'%s.*'}",string(db))

	res,errr := proApi.Query(ctx,q,time.Time{})
	if errr != nil {
		fmt.Println("prometheus mysql uptime error: ",errr.Error())
	}
	m,ok := res.(model.Vector)
	if ok && m.Len() > 0 {
		uptime = fmt.Sprintf("%.1f Days",float64(m[0].Value)/(3600*24))
		//poolsize = fmt.Sprintf("%.2fG",math.Floor(float64(m[0].Value)/(3600*24))
	}

	return
}

func (db Mysql)CurrQps() (currops string, err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()

	q := fmt.Sprintf("irate(mysql_global_status_queries{instance=~'%s.*'}[5m])",string(db))

	res,errr := proApi.Query(ctx,q,time.Time{})
	if errr != nil {
		fmt.Println("prometheus mysql uptime error: ",errr.Error())
	}
	m,ok := res.(model.Vector)
	if ok && m.Len() > 0 {
		currops = fmt.Sprintf("%.2f",float64(m[0].Value))
		//fmt.Println("curr qps is " ,currops )
	}

	return
}

func (db Mysql)CurrSlowQuerys() (slow string, err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()

	q := fmt.Sprintf("irate(mysql_global_status_slow_queries{instance=~'%s.*'}[5m])",string(db))

	res,errr := proApi.Query(ctx,q,time.Time{})
	if errr != nil {
		fmt.Println("prometheus mysql uptime error: ",errr.Error())
	}
	m,ok := res.(model.Vector)
	if ok && m.Len() > 0 {
		slow = fmt.Sprintf("%.2f",float64(m[0].Value))
		fmt.Println("slow querys is  " ,slow )
	}

	return
}

func (db Mysql)BufferPoolSize() (poolsize string, err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()

	q := fmt.Sprintf("mysql_global_variables_innodb_buffer_pool_size{instance=~'%s.*'}",string(db))

	res,errr := proApi.Query(ctx,q,time.Time{})
	if errr != nil {
		fmt.Println("prometheus mysql uptime error: ",errr.Error())
	}
	m,ok := res.(model.Vector)
	if ok && m.Len() > 0 {
		poolsize = fmt.Sprintf("%.2fG",float64(m[0].Value)/1024/1024/1024)

	}

	return
}


type MysqlRange struct {
	T []string
	X1,X2,X3 []float64

}

func (db Mysql) Connectios() (mysqlconn MysqlRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()
	queryList := []string{"mysql_global_status_max_used_connections","mysql_global_status_threads_connected","mysql_global_variables_max_connections"}

	for i,query :=range queryList {
		q := fmt.Sprintf("%s{instance=~'%s.*'}",query,string(db))
		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			//fmt.Println("m[0] is ",m[0].Metric)
			//fmt.Println("m[0] is ",m[0].Values)
			v := m[0].Values

			//fmt.Println(reflect.TypeOf(m[0].Values))
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny := math.Ceil(y)
				if i == 0 { //receive network io rate
					mysqlconn.T = append(mysqlconn.T , t)
					mysqlconn.X1 = append(mysqlconn.X1,ny)
				} else if i == 1 {
					mysqlconn.X2 = append(mysqlconn.X2,ny)
				} else if i == 2 {
					mysqlconn.X3 = append(mysqlconn.X3,ny)
				}
			}
		}
		//fmt.Println("ok is " , ok)
		//fmt.Println("m is " , m.Len())
	}
	fmt.Println("mysql connect status is  ," , mysqlconn)

	return
}

func (db Mysql) ClientThreads() (threads MysqlRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()
	queryList := []string{"mysql_global_status_threads_connected","mysql_global_status_threads_running","mysql_global_status_threads_running"}

	for i,query :=range queryList {

		q := fmt.Sprintf("max_over_time(%s{instance=~'%s.*'}[5m])",query,string(db))
		if i == 2 {
			q = fmt.Sprintf("avg_over_time(%s{instance=~'%s.*'}[5m])",query,string(db))
		}

		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			v := m[0].Values
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny := math.Ceil(y)
				if i == 0 { //receive network io rate
					threads.T = append(threads.T , t)
					threads.X1 = append(threads.X1,ny)
				} else if i == 1 {
					threads.X2 = append(threads.X2,ny)
				} else if i == 2 {
					threads.X3 = append(threads.X3,ny)
				}
			}
		}
		//fmt.Println("ok is " , ok)
		//fmt.Println("m is " , m.Len())
	}
	//fmt.Println("mysql client threads is  ," , threads)
	return
}


func (db Mysql)Questions() (questions MysqlRange, err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()
	queryList := []string{"mysql_global_status_questions"}  //Questions的计数器，当客户端发送一个查询语句后，其值就会+1,监控吞吐量

	for i,query :=range queryList {

		q := fmt.Sprintf(" irate(%s{instance=~'%s.*'}[5m])",query,string(db))

		fmt.Println("client threads query is ", q)
		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			v := m[0].Values
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				//y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
				if i == 0 { //receive network io rate
					questions.T = append(questions.T , t)
					questions.X1 = append(questions.X1,ny)
				} else if i == 1 {
					questions.X2 = append(questions.X2,ny)
				} else if i == 2 {
					questions.X3 = append(questions.X3,ny)
				}
			}
		}

	}
	fmt.Println("mysql questions rate is  ," , questions)

	return
}

func (db Mysql) ThreadCache() (threadcache MysqlRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()
	queryList := []string{"mysql_global_variables_thread_cache_size","mysql_global_status_threads_cached","mysql_global_status_threads_created"}

	for i,query :=range queryList {

		q := fmt.Sprintf("%s{instance=~'%s.*'}",query,string(db))
		if i == 2 {
			q = fmt.Sprintf("irate(%s{instance=~'%s.*'}[5m])",query,string(db))
		}

		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			v := m[0].Values
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
				if i == 0 { //receive network io rate
					threadcache.T = append(threadcache.T , t)
					threadcache.X1 = append(threadcache.X1,ny)
				} else if i == 1 {
					threadcache.X2 = append(threadcache.X2,ny)
				} else if i == 2 {
					threadcache.X3 = append(threadcache.X3,ny)
				}
			}
		}
		//fmt.Println("ok is " , ok)
		//fmt.Println("m is " , m.Len())
	}
	//fmt.Println("mysql  threads  cache is  ," , threadcache)
	return
}

//abort
func (db Mysql) AbortConnections() (aborts MysqlRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()
	/*
	aborted_connections 表示尝试连接到mysql服务器的失败次数;密码错误，没有权限，连接超时，连接信息不正确
	aborted_clients 客户端没有主动断开，客户端休眠时间超出mysql系统变量wait_timeout和interactive_timeout的值，客户端程序在数据传输中突然结束
	*/
	queryList := []string{"mysql_global_status_aborted_connects","mysql_global_status_aborted_clients","node_sockstat_TCP_tw"}


	for i,query :=range queryList {

		q := fmt.Sprintf("irate(%s{instance=~'%s.*'}[5m])",query,string(db))
		if i == 2 {
			q = fmt.Sprintf("%s{instance=~'%s.*'}",query,string(db)) //系统es_timewait
		}

		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			v := m[0].Values
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
				if i == 0 { //receive network io rate
					aborts.T = append(aborts.T , t)
					aborts.X1 = append(aborts.X1,ny)
				} else if i == 1 {
					aborts.X2 = append(aborts.X2,ny)
				} else if i == 2 {
					aborts.X3 = append(aborts.X3,ny)
				}
			}
		}
		//fmt.Println("ok is " , ok)
		//fmt.Println("m is " , m.Len())
	}
	//fmt.Println("mysql  aborted  connections is  ," , aborts)
	return
}

func (db Mysql) TableLocks() (locks MysqlRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()
	/*
	aborted_connections 表示尝试连接到mysql服务器的失败次数;密码错误，没有权限，连接超时，连接信息不正确
	aborted_clients 客户端没有主动断开，客户端休眠时间超出mysql系统变量wait_timeout和interactive_timeout的值，客户端程序在数据传输中突然结束
	*/
	queryList := []string{"mysql_global_status_table_locks_immediate","mysql_global_status_table_locks_waited"} //wait数量代表锁表数，应该设置报警

	for i,query :=range queryList {

		q := fmt.Sprintf("irate(%s{instance=~'%s.*'}[5m])",query,string(db))

		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			v := m[0].Values
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
				if i == 0 { //receive network io rate
					locks.T = append(locks.T , t)
					locks.X1 = append(locks.X1,ny)
				} else if i == 1 {
					locks.X2 = append(locks.X2,ny)
				} else if i == 2 {
					locks.X3 = append(locks.X3,ny)
				}
			}
		}
		//fmt.Println("ok is " , ok)
		//fmt.Println("m is " , m.Len())
	}
	fmt.Println("mysql  table locks   is  ," , locks)
	return
}

func (db Mysql) NetWorkTraffic() (traffic MysqlRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()

	queryList := []string{"mysql_global_status_bytes_received","mysql_global_status_bytes_sent"}

	for i,query :=range queryList {

		q := fmt.Sprintf("irate(%s{instance=~'%s.*'}[5m])",query,string(db))

		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			v := m[0].Values
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y/1024), 64)  //单位为KB
				if i == 0 { //receive network io rate
					traffic.T = append(traffic.T , t)
					traffic.X1 = append(traffic.X1,ny)
				} else if i == 1 {
					traffic.X2 = append(traffic.X2,ny)
				} else if i == 2 {
					traffic.X3 = append(traffic.X3,ny)
				}
			}
		}
	}
	//fmt.Println("mysql  network traffic   is  ," , traffic)
	return
}

func (db Mysql) NetWorkUsageHourly() (usage MysqlRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()

	queryList := []string{"mysql_global_status_bytes_received","mysql_global_status_bytes_sent"}

	for i,query :=range queryList {

		q := fmt.Sprintf("increase(%s{instance=~'%s.*'}[1h])",query,string(db))

		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60 * 24),    //一小时内的
			Step: 3600 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			v := m[0].Values
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y/1024/1024), 64)  //单位为MB
				if i == 0 { //receive network io rate
					usage.T = append(usage.T , t)
					usage.X1 = append(usage.X1,ny)
				} else if i == 1 {
					usage.X2 = append(usage.X2,ny)
				} else if i == 2 {
					usage.X3 = append(usage.X3,ny)
				}
			}
		}
	}
	//fmt.Println("mysql  network hourly usage last 24 hours   is  ," , usage)
	return
}

func (db Mysql) InternalMemory() (mysqlconn MysqlRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()
	queryList := []string{"mysql_global_variables_innodb_log_buffer_size","mysql_global_variables_query_cache_size","mysql_global_status_buffer_pool_pages"}

	for i,query :=range queryList {
		q := fmt.Sprintf("%s{instance=~'%s.*'}",query,string(db))
		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)
		m,ok := res.(model.Matrix)
		if ok && m.Len() > 0 {
			//fmt.Println("m[0] is ",m[0].Metric)
			//fmt.Println("m[0] is ",m[0].Values)
			v := m[0].Values

			//fmt.Println(reflect.TypeOf(m[0].Values))
			for _,samplepair := range v {
				t := samplepair.Timestamp.Time().Format("15:04")
				y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
				ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y/1024/1024), 64)  //单位为MB
				if i == 0 { //receive network io rate
					mysqlconn.T = append(mysqlconn.T , t)
					mysqlconn.X1 = append(mysqlconn.X1,ny)
				} else if i == 1 {
					mysqlconn.X2 = append(mysqlconn.X2,ny)
				} else if i == 2 {
					fmt.Println("ys is y",y)
					ny,_ = strconv.ParseFloat(fmt.Sprintf("%.2f", y*16384/1024/1024), 64)  //pagesize = 16KB
					mysqlconn.X3 = append(mysqlconn.X3,ny)
				}
			}
		}
		//fmt.Println("ok is " , ok)
		//fmt.Println("m is " , m.Len())
	}
	fmt.Println("mysql internal memory overview is  ," , mysqlconn)

	return
}

//command,handels,process
//top5 command handels
type MerticRange struct {
	T []string
	Mertic []string
	X1,X2,X3,X4,X5 []float64

}

func (db Mysql) Top5Commands() (top MerticRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()


		q := fmt.Sprintf("topk(4, irate(mysql_global_status_commands_total{instance=~'%s.*'}[5m])>0)",string(db))  //why 4??
		fmt.Println("this q is" , q)
		r := v1.Range{
			End: time.Now(),
			Start: time.Now().Add(-time.Minute * 60),    //一小时内的
			Step: 300 * time.Second,
		}
		res,errr := proApi.QueryRange(ctx,q,r)
		if errr != nil {
			fmt.Println("disk io error is",errr.Error())
		}
		//fmt.Println("disk io data is " , res)


		m,ok := res.(model.Matrix)
		fmt.Println("this mertic len" ,m.Len() )
		fmt.Println("ok is " , ok)
		if ok {
			fmt.Println("~~~~~~~~~~~~~~")
			for i,v := range m {
				fmt.Println("iiiiiiiiiiiiiii is" ,i)
				fmt.Println("mertic is " , string(v.Metric["command"]))
				top.Mertic = append(top.Mertic,string(v.Metric["command"]))
				//var tmprange MysqlRange
				switch i {
				case 0:
					for _,samplepair := range v.Values {
						t := samplepair.Timestamp.Time().Format("15:04")
						y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
						ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
						top.T = append(top.T , t)
						top.X1 = append(top.X1,ny)
					}
				case 1:
					for _,samplepair := range v.Values {
						//t := samplepair.Timestamp.Time().Format("15:04")
						y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
						ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

						top.X2 = append(top.X2,ny)
					}
				case 2:
					for _,samplepair := range v.Values {
						//t := samplepair.Timestamp.Time().Format("15:04")
						y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
						ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

						top.X3 = append(top.X3,ny)
					}
				case 3:
					for _,samplepair := range v.Values {
						//t := samplepair.Timestamp.Time().Format("15:04")
						y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
						ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

						top.X4 = append(top.X4,ny)
					}
				case 4:
					for _,samplepair := range v.Values {
						t := samplepair.Timestamp.Time().Format("15:04")
						fmt.Println("t5 is ", t)
						y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
						ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
						top.X5 = append(top.X5,ny)
					}
				}

				//top[string(v.Metric["command"])] = tmprange

			}
		}
		//fmt.Println("ok is " , ok)
		//fmt.Println("m is " , m.Len())

	//fmt.Println("mysql top5 commands  overview is  ," , top)

	return
}

func (db Mysql) Top5Commandshourly() (top MerticRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()


	q := fmt.Sprintf("topk(4, increase(mysql_global_status_commands_total{instance=~'%s.*'}[1h])>0)",string(db))
	r := v1.Range{
		End: time.Now(),
		Start: time.Now().Add(-time.Minute * 60 * 24),    //一小时内的
		Step: 3600 * time.Second,
	}
	res,errr := proApi.QueryRange(ctx,q,r)
	if errr != nil {
		fmt.Println("disk io error is",errr.Error())
	}
	//fmt.Println("disk io data is " , res)
	m,ok := res.(model.Matrix)
	fmt.Println("this mertic len" ,m.Len() )
	fmt.Println("ok is " , ok)
	if ok {
		fmt.Println("~~~~~~~~~~~~~~")
		for i,v := range m {
			fmt.Println("iiiiiiiiiiiiiii is" ,i)
			fmt.Println("mertic is " , string(v.Metric["command"]))
			top.Mertic = append(top.Mertic,string(v.Metric["command"]))
			//var tmprange MysqlRange
			switch i {
			case 0:
				for _,samplepair := range v.Values {
					t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
					top.T = append(top.T , t)
					top.X1 = append(top.X1,ny)
				}
			case 1:
				for _,samplepair := range v.Values {
					//t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

					top.X2 = append(top.X2,ny)
				}
			case 2:
				for _,samplepair := range v.Values {
					//t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

					top.X3 = append(top.X3,ny)
				}
			case 3:
				for _,samplepair := range v.Values {
					//t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

					top.X4 = append(top.X4,ny)
				}
			case 4:
				for _,samplepair := range v.Values {
					t := samplepair.Timestamp.Time().Format("15:04")
					fmt.Println("t5 is ", t)
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
					top.X5 = append(top.X5,ny)
				}
			}

			//top[string(v.Metric["command"])] = tmprange

		}
	}
	//fmt.Println("ok is " , ok)
	//fmt.Println("m is " , m.Len())

	//fmt.Println("mysql top5 commands  hourly is overview is  ," , top)

	return
}


func (db Mysql) TransactionHandlers() (top MerticRange,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()


	q := fmt.Sprintf("irate(mysql_global_status_handlers_total{instance=~'%s.*',handler=~'commit|rollback|savepoint.*|prepare'}[5m])",string(db))
	r := v1.Range{
		End: time.Now(),
		Start: time.Now().Add(-time.Minute * 60),    //一小时内的
		Step: 300 * time.Second,
	}
	res,errr := proApi.QueryRange(ctx,q,r)
	if errr != nil {
		fmt.Println("disk io error is",errr.Error())
	}
	//fmt.Println("disk io data is " , res)
	m,ok := res.(model.Matrix)
	fmt.Println("this mertic len" ,m.Len() )
	fmt.Println("ok is " , ok)
	if ok {
		fmt.Println("~~~~~~~~~~~~~~")
		for i,v := range m {
			fmt.Println("iiiiiiiiiiiiiii is" ,i)
			fmt.Println("mertic is " , string(v.Metric["handler"]))
			top.Mertic = append(top.Mertic,string(v.Metric["handler"]))
			//var tmprange MysqlRange
			switch i {
			case 0:
				for _,samplepair := range v.Values {
					t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)
					top.T = append(top.T , t)
					top.X1 = append(top.X1,ny)
				}
			case 1:
				for _,samplepair := range v.Values {
					//t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

					top.X2 = append(top.X2,ny)
				}
			case 2:
				for _,samplepair := range v.Values {
					//t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

					top.X3 = append(top.X3,ny)
				}
			case 3:
				for _,samplepair := range v.Values {
					//t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

					top.X4 = append(top.X4,ny)
				}
			case 4:
				for _,samplepair := range v.Values {
					//t := samplepair.Timestamp.Time().Format("15:04")
					y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
					ny,_ := strconv.ParseFloat(fmt.Sprintf("%.2f", y), 64)

					top.X5 = append(top.X5,ny)
				}
			}

			//top[string(v.Metric["command"])] = tmprange

		}
	}
	//fmt.Println("ok is " , ok)
	//fmt.Println("m is " , m.Len())

	fmt.Println("mysql 事务处理器 overview is  ," , top)

	return
}
